using System;
using System.Web;
using log4net;
using Microsoft.Practices.ServiceLocation;
using NHibernate;
using NHibernate.Context;

namespace SIP.PN.FrontEnd.Code.HttpModules
{
    public class HttpModuleNHibernateSession : IHttpModule
    {
        private readonly ILog logger = LogManager.GetLogger(typeof(HttpModuleNHibernateSession));

        #region IHttpModule Members

        public void Init(HttpApplication context)
        {

            context.BeginRequest += OpenSession;
            context.EndRequest += CloseSession;
        }

        public void Dispose()
        {
        }

        #endregion

        private void OpenSession(object sender, EventArgs e)
        {
            if (HttpContext.Current != null)
            {
                logger.Info(string.Format("request: {0}?{1}", HttpContext.Current.Request.Url.PathAndQuery, HttpContext.Current.Request.Params));
            }
            else
                logger.Info("request: ??");

            try
            {
                if (!RequestMayNeedIterationWithPersistence(sender as HttpApplication))
                    return;

                ISessionFactory sessionFactory = ServiceLocator.Current.GetInstance<ISessionFactory>("ISessionFactoryWEB");
                ISession session = sessionFactory.OpenSession();
                logger.Info(string.Format("Abriendo session: {0}", session.GetHashCode()));
                CurrentSessionContext.Bind(session);
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
        }

        private void CloseSession(object sender, EventArgs e)
        {
            try
            {
                if (!RequestMayNeedIterationWithPersistence(sender as HttpApplication))
                    return;

                ISessionFactory sessionFactory = ServiceLocator.Current.GetInstance<ISessionFactory>("ISessionFactoryWEB");

                ISession session = sessionFactory.GetCurrentSession();
                session.Close();
                logger.Info(string.Format("Cerrando session: {0}", session.GetHashCode()));

                CurrentSessionContext.Unbind(sessionFactory);
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
        }

        private static bool RequestMayNeedIterationWithPersistence(HttpApplication application)
        {
            if (application == null)
            {
                return false;
            }

            HttpContext context = application.Context;
            return context != null && !context.Request.FilePath.EndsWith(".js") && !context.Request.FilePath.EndsWith(".jpg") && !context.Request.FilePath.EndsWith(".gif") && !context.Request.FilePath.EndsWith(".png") && !context.Request.FilePath.EndsWith(".css");
        }
    }
}
